/*
 * Copyright (c) 2024 iSoftStone Education Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <stdbool.h>
#include <math.h>
#include <string.h>
#include <unistd.h>
#include "los_task.h"
#include "los_tick.h"    // 替换 los_sys.h 为 los_tick.h
#include "ohos_init.h"
#include "lz_hardware.h"

/* ADC通道定义 */
#define ADC_CHANNEL 5  // 使用与adc_example.c相同的通道

/* 定义ADC初始化的结构体 */
static DevIo m_adcKey = {
    .isr =   {.gpio = INVALID_GPIO},
    .rst =   {.gpio = INVALID_GPIO},
    .ctrl1 = {.gpio = GPIO0_PC5, .func = MUX_FUNC1, .type = PULL_NONE, .drv = DRIVE_KEEP, .dir = LZGPIO_DIR_IN, .val = LZGPIO_LEVEL_KEEP},
    .ctrl2 = {.gpio = INVALID_GPIO},
};

/* 按键电压阈值定义 */
#define KEY_VOLTAGE_NONE  3.0f    // 无按键按下时的电压阈值
#define KEY_VOLTAGE_LEFT  2.0f    // LEFT键电压阈值
#define KEY_VOLTAGE_DOWN  1.5f    // DOWN键电压阈值
#define KEY_VOLTAGE_RIGHT 0.8f    // RIGHT键电压阈值
#define KEY_VOLTAGE_UP    0.3f    // UP键电压阈值

/* 电压检测参数 */
#define VOLTAGE_CHANGE_THRESHOLD 0.1f   // 电压变化阈值
#define VOLTAGE_STABLE_COUNT 2          // 需要连续稳定的次数
#define VOLTAGE_CHECK_INTERVAL 100      // 电压检测间隔(ms)
#define TEST_DURATION 60               // 测试持续时间(秒)

/* 系统时钟定义 */
#define OS_SYS_CLOCK 100              // 系统时钟频率(Hz)

/* 童锁状态标志 */
static bool g_childLockEnabled = false;

/***************************************************************
* 函数名称: EnableChildLock
* 说    明: 启用/禁用童锁
* 参    数: enable - true启用童锁，false禁用童锁
* 返 回 值: 无
***************************************************************/
void EnableChildLock(bool enable)
{
    g_childLockEnabled = enable;
    printf("Child Lock %s\n", enable ? "Enabled" : "Disabled");
}

/***************************************************************
* 函数名称: IsChildLockEnabled
* 说    明: 获取童锁状态
* 参    数: 无
* 返 回 值: true-童锁已启用，false-童锁未启用
***************************************************************/
bool IsChildLockEnabled(void)
{
    return g_childLockEnabled;
}

/***************************************************************
* 函数名称: adc_dev_init
* 说    明: 初始化ADC
* 参    数: 无
* 返 回 值: 0为成功，反之为失败
***************************************************************/
static unsigned int adc_dev_init()
{
    unsigned int ret = 0;
    uint32_t *pGrfSocCon29 = (uint32_t *)(0x41050000U + 0x274U);
    uint32_t ulValue;

    // 初始化GPIO
    ret = DevIoInit(m_adcKey);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("%s, %s, %d: ADC Key IO Init fail\n", __FILE__, __func__, __LINE__);
        return __LINE__;
    }

    // 初始化SARADC
    ret = LzSaradcInit();
    if (ret != LZ_HARDWARE_SUCCESS) {
        printf("%s, %s, %d: ADC Init fail\n", __FILE__, __func__, __LINE__);
        return __LINE__;
    }

    /* 设置saradc的电压信号，选择AVDD */
    ulValue = *pGrfSocCon29;
    ulValue &= ~(0x1 << 4);
    ulValue |= ((0x1 << 4) << 16);
    *pGrfSocCon29 = ulValue;
    
    return 0;
}

/***************************************************************
* 函数名称: adc_get_voltage
* 说    明: 获取ADC电压值
* 参    数: 无
* 返 回 值: 电压值
***************************************************************/
float adc_get_voltage()
{
    unsigned int ret = LZ_HARDWARE_SUCCESS;
    unsigned int data = 0;

    // 如果童锁启用，始终返回高电平
    if (IsChildLockEnabled()) {
        return 3.3f;  // 返回最高电平
    }

    ret = LzSaradcReadValue(ADC_CHANNEL, &data);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("%s, %s, %d: ADC Read Fail\n", __FILE__, __func__, __LINE__);
        return 0.0;
    }

    return (float)(data * 3.3 / 1024.0);
}

/***************************************************************
* 函数名称: GetKeyTypeByVoltage
* 说    明: 根据电压值判断按键类型
* 参    数: voltage - 电压值
* 返 回 值: 按键类型字符串
***************************************************************/
static const char* GetKeyTypeByVoltage(float voltage)
{
    if (voltage >= KEY_VOLTAGE_NONE) return "NONE";
    else if (voltage >= KEY_VOLTAGE_LEFT) return "LEFT";
    else if (voltage >= KEY_VOLTAGE_DOWN) return "DOWN";
    else if (voltage >= KEY_VOLTAGE_RIGHT) return "RIGHT";
    else if (voltage >= KEY_VOLTAGE_UP) return "UP";
    else return "INVALID";
}

/***************************************************************
* 函数名称: IsVoltageStable
* 说    明: 检查电压是否稳定
* 参    数: voltage - 当前电压值
*          lastVoltage - 上次电压值
* 返 回 值: true-电压稳定，false-电压不稳定
***************************************************************/
static bool IsVoltageStable(float voltage, float lastVoltage)
{
    return fabs(voltage - lastVoltage) < VOLTAGE_CHANGE_THRESHOLD;
}

/***************************************************************
* 函数名称: PrintKeyStatus
* 说    明: 打印按键状态
* 参    数: voltage - 电压值
*          locked - 是否处于锁定状态
* 返 回 值: 无
***************************************************************/
static void PrintKeyStatus(float voltage, bool locked)
{
    const char* keyType = GetKeyTypeByVoltage(voltage);
    if (strcmp(keyType, "NONE") != 0) {
        
    }
}
/***************************************************************
* 函数名称: adc_process
* 说    明: ADC采集循环任务
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void adc_process()
{
    float voltage = 0, lastVoltage = 0;
    uint32_t stableCount = 0;
    /* 初始化adc设备 */
    adc_dev_init();
    while (1)
    {
        voltage = adc_get_voltage();
        // 检查童锁状态
        if (IsChildLockEnabled()) {
            LOS_Msleep(VOLTAGE_CHECK_INTERVAL);
            continue;
        }
        // 检查电压是否稳定
        if (IsVoltageStable(voltage, lastVoltage)) {
            stableCount++;
            if (stableCount >= VOLTAGE_STABLE_COUNT) {
                const char* currentKeyType = GetKeyTypeByVoltage(voltage);
                if (strcmp(currentKeyType, "NONE") != 0) {
                    PrintKeyStatus(voltage, false);
                }
            }
        } else {
            stableCount = 0;
        }
        
        lastVoltage = voltage;
        LOS_Msleep(VOLTAGE_CHECK_INTERVAL);
    }
}

/***************************************************************
* 函数名称: adc_example
* 说    明: 开机自启动调用函数
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void adc_example()
{
    unsigned int thread_id;
    TSK_INIT_PARAM_S task = {0};
    unsigned int ret = LOS_OK;

    // 创建ADC处理任务
    task.pfnTaskEntry = (TSK_ENTRY_FUNC)adc_process;
    task.uwStackSize = 2048;
    task.pcName = "adc process";
    task.usTaskPrio = 24;
    ret = LOS_TaskCreate(&thread_id, &task);
    if (ret != LOS_OK)
    {
        printf("Failed to create ADC task ret:0x%x\n", ret);
        return;
    }
}

APP_FEATURE_INIT(adc_example);